import { isNumber } from 'qx-util';
import {
	PanelButtonController,
	PanelContainerController,
	PanelControlController,
	PanelCtrlPosController,
	PanelFieldController,
	PanelRawItemController,
	PanelTabPageController,
	PanelTabPanelController,
	PanelUserControlController,
} from '../controller';
import { IContext, ILayoutOpts, IParam } from '../interface';

/**
 * 布局逻辑工具类
 *
 * @export
 * @class LayoutUtil
 */
export class LayoutUtil {
	/**
	 * 获取flex布局样式（父容器）
	 *
	 * @static
	 * @param {*} layoutOpts 布局设置
	 * @returns {string}
	 * @memberof LayoutUtil
	 */
	public static getRowFlexStyle(layoutOpts: ILayoutOpts): IParam {
		let cssStyle: IParam = {};
		if (layoutOpts?.selfLayout == 'FLEX') {
			const { dir, align, vAlign } = layoutOpts;
			Object.assign(cssStyle, {
				width: '100%',
				height: '100%',
				overflow: 'auto',
				display: 'flex',
			});
			if (dir) {
				Object.assign(cssStyle, { 'flex-direction': dir });
			}
			if (align) {
				Object.assign(cssStyle, { 'justify-content': align });
			}
			if (vAlign) {
				Object.assign(cssStyle, { 'align-items': vAlign });
			}
		}
		return cssStyle;
	}

	/**
	 * 计算Flex 大小
	 *
	 * @static
	 * @param {number} size
	 * @return {*}
	 * @memberof LayoutUtil
	 */
	static calcFlexStyleSize(size: number): string {
		if (isNumber(size)) {
			if (size > 0 && size <= 1) {
				return `${size * 100}%`;
			} else if (size > 1) {
				return `${size}px`;
			}
		}
		return '';
	}

	/**
	 * 获取flex布局样式2(子)
	 *
	 * @static
	 * @param {*} layoutOpts 布局位置
	 * @returns {string}
	 * @memberof LayoutUtil
	 */
	static getColFlexStyle(layoutOpts: ILayoutOpts): IParam {
		let cssStyle: IParam = {};
		if (layoutOpts?.parentLayout == 'FLEX') {
			const grow = layoutOpts.grow! < 0 ? 0 : layoutOpts.grow || 0;
			const width = this.calcFlexStyleSize(layoutOpts.width || 0);
			const height = this.calcFlexStyleSize(layoutOpts.height || 0);
			Object.assign(cssStyle, { grow });
			if (width) {
				Object.assign(cssStyle, { width });
			} else if (grow > 0) {
				Object.assign(cssStyle, { 'min-width': 0 });
			}
			if (height) {
				Object.assign(cssStyle, { height });
			} else if (grow > 0) {
				Object.assign(cssStyle, { 'min-height': 0 });
			}
		}
		return cssStyle;
	}

	/**
	 * 获取栅格布局参数
	 *
	 * @static
	 * @param {*} layoutOpts
	 * @memberof LayoutUtil
	 */
	static getGridOptions(layoutOpts: ILayoutOpts, isTurn24: boolean = true) {
		if (
			!layoutOpts ||
			(layoutOpts.parentLayout != 'TABLE_24COL' &&
				layoutOpts.parentLayout != 'TABLE_12COL')
		) {
			return;
		}
		let colLG = this.formatColSpan(layoutOpts.colLG, layoutOpts.parentLayout);
		let colMD = this.formatColSpan(layoutOpts.colMD, layoutOpts.parentLayout);
		let colSM = this.formatColSpan(layoutOpts.colSM, layoutOpts.parentLayout);
		let colXS = this.formatColSpan(layoutOpts.colXS, layoutOpts.parentLayout);
		let colLGOffset = isNumber(layoutOpts.colLGOffset)
			? layoutOpts.colLGOffset
			: 0;
		let colMDOffset = isNumber(layoutOpts.colMDOffset)
			? layoutOpts.colMDOffset
			: 0;
		let colSMOffset = isNumber(layoutOpts.colSMOffset)
			? layoutOpts.colSMOffset
			: 0;
		let colXSOffset = isNumber(layoutOpts.colXSOffset)
			? layoutOpts.colXSOffset
			: 0;
		let multiplier = 1;
		if (isTurn24) {
			multiplier = layoutOpts.parentLayout == 'TABLE_24COL' ? 1 : 2;
		}
		return {
			span: { span: colXS * multiplier, offset: colXSOffset! * multiplier },
			sm: { span: colSM * multiplier, offset: colSMOffset! * multiplier },
			md: { span: colMD * multiplier, offset: colMDOffset! * multiplier },
			lg: { span: colLG * multiplier, offset: colLGOffset! * multiplier },
		};
	}

	/**
	 * 格式化栅格的列宽,对超出范围值的作出修改或设置默认值
	 *
	 * @static
	 * @param {*} span 栅格列宽
	 * @param {string} layoutMode 栅格类型(TABLE_24COL,TABLE_12COL)
	 * @returns
	 * @memberof LayoutUtil
	 */
	static formatColSpan(span: any, layoutMode: string) {
		let colDefault = layoutMode == 'TABLE_24COL' ? 24 : 12;
		// 空值传默认值
		if (!isNumber(span)) {
			return colDefault;
		}
		// 小于0传默认值，大于默认值传默认值，其他传原值
		if (span < 0 || span > colDefault) {
			return colDefault;
		} else {
			return span;
		}
	}

	/**
	 * 获取盒子大小（宽高模式针对面板项，按钮等项模型是控制的布局内容的宽高）
	 * @param mode 模式 "WIDTH" | "HEIGHT"
	 * @param style 样式 "FULL"(全部宽度) | "PX"（像素） | "PERCENTAGE"（百分比）
	 * @param value
	 * @returns
	 */
	public static getBoxSize(
		mode: 'WIDTH' | 'HEIGHT',
		style: string,
		value: number
	) {
		if (!mode) {
			return {};
		}
		if (!style) {
			style = 'PX';
		}
		if (style === 'FULL') {
			return { [mode.toLowerCase()]: '100%' };
		} else {
			if (!value) {
				return {};
			} else if (style === 'PERCENTAGE') {
				return { [mode.toLowerCase()]: `${value}%` };
			} else {
				return { [mode.toLowerCase()]: `${value}px` };
			}
		}
	}

	/**
	 * 获取项间隔样式
	 *
	 * @param {string} spacingType
	 * @param {string} direction
	 * @return {*}
	 */
	public static getItemSpacingStyle(spacingType: string, direction: string) {
		switch (spacingType) {
			case 'OUTERNONE':
				return { [`margin-${direction}`]: '0px' };
			case 'OUTERSMALL':
				return { [`margin-${direction}`]: '8px' };
			case 'OUTERMEDIUM':
				return { [`margin-${direction}`]: '16px' };
			case 'OUTERLARGE':
				return { [`margin-${direction}`]: '24px' };
			case 'INNERNONE':
				return { [`padding-${direction}`]: '0px' };
			case 'INNERSMALL':
				return { [`padding-${direction}`]: '8px' };
			case 'INNERMEDIUM':
				return { [`padding-${direction}`]: '16px' };
			case 'INNERLARGE':
				return { [`padding-${direction}`]: '24px' };
			default:
				return {};
		}
	}

	/**
	 * 获取布局项实例
	 *
	 * @static
	 * @param {*} layoutModel
	 * @memberof Util
	 */
	public static getLayoutItemInstance(layoutModelItem: any, context: IContext, viewParams: IParam): any {
		if (!layoutModelItem || !layoutModelItem.itemType) {
			throw new Error('获取布局项实例异常');
		}
		switch (layoutModelItem.itemType) {
			case 'CONTAINER':
				return new PanelContainerController(layoutModelItem, context, viewParams);
			case 'RAWITEM':
				return new PanelRawItemController(layoutModelItem, context, viewParams);
			case 'FIELD':
				return new PanelFieldController(layoutModelItem, context, viewParams);
			case 'CONTROL':
				return new PanelControlController(layoutModelItem, context, viewParams);
			case 'BUTTON':
				return new PanelButtonController(layoutModelItem, context, viewParams);
			case 'USERCONTROL':
				return new PanelUserControlController(layoutModelItem, context, viewParams);
			case 'TABPANEL':
				return new PanelTabPanelController(layoutModelItem, context, viewParams);
			case 'CTRLPOS':
				return new PanelCtrlPosController(layoutModelItem, context, viewParams);
			case 'TABPAGE':
				return new PanelTabPageController(layoutModelItem, context, viewParams);
			default:
				throw new Error(`${layoutModelItem.itemType}暂不支持`);
		}
	}
}
